#ifndef PW_PBL_NAMEDTUPLE_HPP
#define PW_PBL_NAMEDTUPLE_HPP

#include "Meta/Enum.hpp"
#include "NamedType.hpp"
#include "Tuple.hpp"

namespace pw_pbl
{
	template <ccNamedType... TNs>
	struct NamedTuple : public Tuple<typename TNs::type...>
	{
	private:
		using _base = Tuple<typename TNs::type...>;
		using _name = Meta::Enum<TNs::name...>;

	public:
		template <typename... T>
		constexpr NamedTuple(T &&...t) : _base{{{std::forward<T>(t)}...}} {}

		template <Meta::Str Name>
		static constexpr size_t EIndex = _name::template index<Name>;

		using _base::get;

		template <Meta::Str Name>
		constexpr decltype(auto) get() noexcept { return std::get<EIndex<Name>>(*this); }
		template <Meta::Str Name>
		constexpr decltype(auto) get() const noexcept { return std::get<EIndex<Name>>(*this); }
	};

	inline namespace literals
	{
		template <Meta::NVPair... NVs>
		constexpr NamedTuple<Meta::Type<typename decltype(NVs.value)::type, NVs.name>...> MetaNamedTuple = {NVs.value()...};
	} // namespace literals
} // namespace pw_pbl

#endif // PW_PBL_NAMEDTUPLE_HPP
